#include "qabstractstylesheetitem.h"

#include <QXmlStreamReader>
#include <QXmlStreamWriter>

using namespace SHAREDLIB;

QAbstractStylesheetItem::QAbstractStylesheetItem(QAbstractStylesheetItem *parent) :
    QObject(parent),
    m_parent(parent),
    m_value("")
{
    if(m_parent!=NULL)
    {
        m_parent->m_children.append(this);
        connect(this,SIGNAL(valueChanged()),m_parent,SLOT(subValueChanged()));
    }
}

QAbstractStylesheetItem::~QAbstractStylesheetItem()
{
    while(m_children.size()>0)
    {
        delete m_children.first();
    }

    if(m_parent!=NULL)
    {
        m_parent->m_children.removeAll(this);
    }
}

QVariant QAbstractStylesheetItem::value()
{
    return m_value;
}

void QAbstractStylesheetItem::setValue(const QVariant &value)
{
    if(m_value!=value)
    {
        m_value=value;
        emit valueChanged();
    }
}

QString QAbstractStylesheetItem::attribute(const QString &key, const QString &def)
{
    return m_attributes.value(key,def);
}

void QAbstractStylesheetItem::setAttribute(const QString &key, const QString &value)
{
    m_attributes.insert(key,value);
}

void QAbstractStylesheetItem::read(QXmlStreamReader *r)
{
    QString value;
    bool setvalue=false;
    m_attributes.clear();
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        if(attribute.name()!="value")
        {
            m_attributes.insert(attribute.name().toString(),attribute.value().toString());
        }
        else
        {
            value=attribute.value().toString();
            setvalue=true;
        }
    }

    QAbstractStylesheetItem *item;

    for(bool finished=false;!finished && !r->hasError();)
    {
        switch(r->readNext())
        {
        case QXmlStreamReader::StartElement:
            item=getChild(r->name().toString());
            if(item!=NULL)
            {
                item->read(r);
            }
            else
            {
                r->raiseError("Property parse error!");
                return;
            }
            break;
        case QXmlStreamReader::EndElement:
            finished=true;
            break;
        default:
            break;
        }
    }

    if(setvalue)
    {
        setValue(value);
    }
}

void QAbstractStylesheetItem::write(QXmlStreamWriter *w)
{
    if(!isUsed())
    {
        return;
    }
    w->writeStartElement(property("type").toString());
    QMapIterator<QString,QString> it(m_attributes);
    while(it.hasNext())
    {
        it.next();
        w->writeAttribute(it.key(),it.value());
    }

    if(m_children.size()==0)
    {
        w->writeAttribute("value",m_value.toString());
    }
    else
    {
        foreach(QAbstractStylesheetItem* item,m_children)
        {
            item->write(w);
        }
    }
    w->writeEndElement();
}

QAbstractStylesheetItem* QAbstractStylesheetItem::getChild(const QString &name)
{
    foreach(QAbstractStylesheetItem* item,m_children)
    {
        if(item->property("type").toString()==name)
        {
            return item;
        }
    }
    return NULL;
}

void QAbstractStylesheetItem::subValueChanged()
{

}

QString QAbstractStylesheetItem::makeStylesheet()
{
    return "";
}

bool QAbstractStylesheetItem::isUsed()
{
    if(m_children.size()>0)
    {
        foreach(QAbstractStylesheetItem* item,m_children)
        {
            if(item->isUsed())
            {
                return true;
            }
        }
        return false;
    }
    else
    {
        if(m_value.toString()==property("default").toString() || m_value.toString()=="")
        {
            return false;
        }
        return true;
    }
}

void QAbstractStylesheetItem::setDefault(const QVariant &value)
{
    setProperty("default",value.toString());
    m_value=value;
}

void QAbstractStylesheetItem::clear()
{
    m_attributes.clear();
    m_value="";
    foreach(QAbstractStylesheetItem* item,m_children)
    {
        item->clear();
    }
}
